1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
use std::ptr::NonNull;
use std::rc::Rc;
use crate::co;
use crate::decl::*;
use crate::gui::{*, events::*, privs::*};
/// Exposes button control
/// [notifications](https://learn.microsoft.com/en-us/windows/win32/controls/bumper-button-control-reference-notifications)
/// for a [`RadioGroup`](crate::gui::RadioGroup).
///
/// These event methods are just proxies to the
/// [`WindowEvents`](crate::gui::events::WindowEvents) of the parent window, who
/// is the real responsible for the child event handling.
///
/// You cannot directly instantiate this object, it is created internally by the
/// control.
pub struct RadioGroupEvents {
parent_ptr: NonNull<Base>,
ctrl_ids: Vec<u16>,
}
impl RadioGroupEvents {
#[must_use]
pub(in crate::gui) fn new(
parent: &impl AsRef<Base>,
ctrl_ids: Vec<u16>,
) -> Self
{
Self {
parent_ptr: NonNull::from(parent.as_ref()),
ctrl_ids,
}
}
#[must_use]
fn parent_user_events(&self) -> &WindowEvents {
unsafe { self.parent_ptr.as_ref().on() }
}
/// [`BN_CLICKED`](https://learn.microsoft.com/en-us/windows/win32/controls/bn-clicked)
/// command notification for all radio buttons in the group.
///
/// Sent when the user clicks a button.
///
/// # Examples
///
/// ```no_run
/// use winsafe::{self as w, prelude::*, gui};
///
/// let wnd: gui::WindowMain; // initialized somewhere
/// # let wnd = gui::WindowMain::new(gui::WindowMainOpts::default());
/// let radios: gui::RadioGroup;
/// # let radios = gui::RadioGroup::new(&wnd, &[]);
///
/// radios.on().bn_clicked({
/// let radios = radios.clone();
/// move || -> w::AnyResult<()> {
/// println!("Selected {}",
/// radios.checked().unwrap()
/// .hwnd().GetWindowText()?,
/// );
/// Ok(())
/// }
/// });
/// ```
pub fn bn_clicked<F>(&self, func: F)
where F: Fn() -> AnyResult<()> + 'static,
{
let shared_func = Rc::new(func);
for ctrl_id in self.ctrl_ids.iter() {
self.parent_user_events().wm_command(*ctrl_id, co::BN::CLICKED, {
let shared_func = shared_func.clone();
move || {
shared_func()?;
Ok(WmRet::HandledOk)
}
});
}
}
/// [`BN_DBLCLK`](https://learn.microsoft.com/en-us/windows/win32/controls/bn-dblclk)
/// command notification for all radio buttons in the group.
///
/// Sent when the user double-clicks a button. This notification code is
/// sent automatically for [`BS::USERBUTTON`](crate::co::BS::USERBUTTON),
/// [`BS::RADIOBUTTON`](crate::co::BS::RADIOBUTTON), and
/// [`BS::OWNERDRAW`](crate::co::BS::OWNERDRAW) buttons. Other button types
/// send only if they have the [`BS::NOTIFY`](crate::co::BS::NOTIFY) style.
pub fn bn_dbl_clk<F>(&self, func: F)
where F: Fn() -> AnyResult<()> + 'static,
{
let shared_func = Rc::new(func);
for ctrl_id in self.ctrl_ids.iter() {
self.parent_user_events().wm_command(*ctrl_id, co::BN::DBLCLK, {
let shared_func = shared_func.clone();
move || {
shared_func()?;
Ok(WmRet::HandledOk)
}
});
}
}
/// [`BN_KILLFOCUS`](https://learn.microsoft.com/en-us/windows/win32/controls/bn-killfocus)
/// command notification for all radio buttons in the group.
///
/// Sent when a button loses the keyboard focus. The button must have the
/// [`BS::NOTIFY`](crate::co::BS::NOTIFY) style to send this notification
/// code.
pub fn bn_kill_focus<F>(&self, func: F)
where F: Fn() -> AnyResult<()> + 'static,
{
let shared_func = Rc::new(func);
for ctrl_id in self.ctrl_ids.iter() {
self.parent_user_events().wm_command(*ctrl_id, co::BN::KILLFOCUS, {
let shared_func = shared_func.clone();
move || {
shared_func()?;
Ok(WmRet::HandledOk)
}
});
}
}
/// [`BN_SETFOCUS`](https://learn.microsoft.com/en-us/windows/win32/controls/bn-setfocus)
/// command notification for all radio buttons in the group.
///
/// Sent when a button receives the keyboard focus. The button must have the
/// [`BS::NOTIFY`](crate::co::BS::NOTIFY) style to send this notification
/// code.
pub fn bn_set_focus<F>(&self, func: F)
where F: Fn() -> AnyResult<()> + 'static,
{
let shared_func = Rc::new(func);
for ctrl_id in self.ctrl_ids.iter() {
self.parent_user_events().wm_command(*ctrl_id, co::BN::SETFOCUS, {
let shared_func = shared_func.clone();
move || {
shared_func()?;
Ok(WmRet::HandledOk)
}
});
}
}
}